﻿using System;
using System.Collections.Generic;
using System.Text;
using System.IO;

namespace BizElements.Generator.OrmComponents
{
    /// <summary>Provides common operation for text manipulation.</summary>
    internal static class TextUtil
    {
        #region StripPrefix.

        /// <summary>Strips prefixes.</summary>
        internal static string StripPrefix(string originalName, string[] prefixesToBeStripped)
        {
            if (prefixesToBeStripped == null)
                return originalName;

            for (int i = 0; i < prefixesToBeStripped.Length; i++)
            {
                if (originalName.StartsWith(prefixesToBeStripped[i], StringComparison.OrdinalIgnoreCase))
                    return originalName.Substring(prefixesToBeStripped[i].Length - 1);
            }

            return originalName;
        }

        #endregion

        static Dictionary<string, List<ReplaceSuffixRule>> ParsedSuffixReplacementMaps = new Dictionary<string, List<ReplaceSuffixRule>>();
        const string SuffixReplacementMapItemDelimiter = ";";
        const string SuffixReplacementMapKeyValueDelimiter = "->";

        internal static string ReplaceSuffixes(string originalText, string suffixReplacementMap)
        {
            List<ReplaceSuffixRule> map = GetParsedSuffixReplacementMap(suffixReplacementMap);
            foreach (ReplaceSuffixRule replaceRule in map)
            {
                // Only 1st rule match is applied.
                bool isRuleApplicable = originalText.EndsWith(replaceRule.OldSuffix, StringComparison.OrdinalIgnoreCase);
                if (isRuleApplicable)
                {
                    string withoutOldSuffix = originalText.Substring(0, originalText.Length - replaceRule.OldSuffix.Length);
                    string withNewSuffix = withoutOldSuffix + replaceRule.NewSuffix;
                    return withNewSuffix;
                }
            }

            // No rule was matched.
            return originalText;
        }

        private static List<ReplaceSuffixRule> GetParsedSuffixReplacementMap(string suffixReplacementMap)
        {
            List<ReplaceSuffixRule> map;
            ParsedSuffixReplacementMaps.TryGetValue(suffixReplacementMap, out map);
            if (map == null)
            {
                map = ParseSuffixRules(suffixReplacementMap, SuffixReplacementMapItemDelimiter, SuffixReplacementMapKeyValueDelimiter);
                ParsedSuffixReplacementMaps[suffixReplacementMap] = map;
            }

            return map;
        }

        private static List<ReplaceSuffixRule> ParseSuffixRules(string delimitedVariables, string variableDelimiter, string keyValueDelimiter)
        {
            // Remove final delimiter if it is accidently provided.
            if (delimitedVariables.EndsWith(variableDelimiter, StringComparison.OrdinalIgnoreCase))
                delimitedVariables = delimitedVariables.Substring(0, delimitedVariables.Length - variableDelimiter.Length);

            string[] keyValuePairs = delimitedVariables.Split(new string[] { variableDelimiter }, StringSplitOptions.None);
            List<ReplaceSuffixRule> rules = new List<ReplaceSuffixRule>(keyValuePairs.Length);
            foreach (string keyAndValue in keyValuePairs)
            {
                int firstDelimiterOccurrence = keyAndValue.IndexOf(keyValueDelimiter, StringComparison.OrdinalIgnoreCase);
                if (firstDelimiterOccurrence < 0)
                    throw new InvalidOperationException("Key-value pair (" + keyAndValue + ") doesn't contain the specified key-value delimiter (" + keyValueDelimiter + ").");

                int keyLen = firstDelimiterOccurrence;
                string key = keyAndValue.Substring(0, keyLen).Replace("\"", "");

                int delimiterLen = keyValueDelimiter.Length;
                int valueStart = firstDelimiterOccurrence + delimiterLen;
                string value = (valueStart < keyAndValue.Length) ? keyAndValue.Substring(valueStart, keyAndValue.Length - valueStart) : string.Empty;
                value = value.Replace("\"", "");

                rules.Add(new ReplaceSuffixRule() { OldSuffix = key, NewSuffix = value });
            }

            return rules;
        }

        private class ReplaceSuffixRule
        {
            public string OldSuffix;
            public string NewSuffix;
        }
    }
}
